# plugs/irc.py
#
#

""" irc related commands """

__copyright__ = 'this file is in the public domain'

from gozerbot.callbacks import callbacks
from gozerbot.commands import cmnds
from gozerbot.examples import examples
from gozerbot.config import config
from gozerbot.plughelp import plughelp
import gozerbot.thr as thr
import Queue

plughelp.add('irc', 'irc related commands')

def dojoin(bot, ievent):
    """ join <channel> [password] """
    try:
        channel = ievent.args[0]
        chan = channel.lower()
    except IndexError:
        ievent.missing("<channel> [password]")
        return
    try:
        password = ievent.args[1]
    except IndexError:
        password = None
    bot.join(chan, password=password)

cmnds.add('join', dojoin, 'OPER')
examples.add('join', 'join <channel> [password]', '1) join #dunkbots 2) \
join #dunkbots mekker')

def delchan(bot, ievent):
    """ delchan <channel>  .. remove channel from bot.channels """
    try:
        chan = ievent.args[0]
    except IndexError:
        ievent.missing("<channel>")
        return
    try:
        del bot.channels[chan]
    except KeyError:
        ievent.reply("no channel %s in database" % chan)
        return
    ievent.reply('%s deleted' % chan)

cmnds.add('delchan', delchan, 'OPER')
examples.add('delchan', 'delchan <channel> .. remove channel from \
bot.channels', 'delchan #mekker')

def dopart(bot, ievent):
    """ part [<channel>] """
    try:
        chan = ievent.args[0]
    except IndexError:
        chan = ievent.channel
    chan = chan.lower()
    bot.part(chan)
    try:
        del bot.channels[chan]
    except:
        pass

cmnds.add('part', dopart, 'OPER')
examples.add('part', 'part [<channel>]', '1) part 2) part #dunkbots')

def handle_channels(bot, ievent):
    """ channels .. show joined channels """
    chans = " ".join(bot.joinedchannels)
    if chans:
        ievent.reply(chans)
    else:
        ievent.reply('no channels joined')

cmnds.add('channels', handle_channels, ['USER', 'WEB'])
examples.add('channels', 'show what channels the bot is on', 'channels')

def handle_chat(bot, ievent):
    """ chat .. start a bot initiated dcc chat session """
    i = ievent
    thr.start_new_thread(bot.dcclisten, (i.nick, i.userhost, i.channel))
    ievent.reply('dcc chat request send')

cmnds.add('chat', handle_chat, 'USER')
examples.add('chat', 'start a dcc chat session', 'chat')

def handle_cycle(bot, ievent):
    """ cycle .. recycle channel """
    bot.part(ievent.channel)
    try:
        key = bot.channels[ievent.channel]['key']
    except KeyError:
        key = None
    bot.join(ievent.channel, password=key)

cmnds.add('cycle', handle_cycle, 'OPER')
examples.add('cycle', 'part/join channel', 'cycle')

def handle_jump(bot, ievent):
    """ jump <server> <port> .. change server """
    if len(ievent.args) != 2:
        ievent.missing('<server> <port>')
        return
    (server, port) = ievent.args
    ievent.reply('changing to server %s' % server)
    bot.shutdown()
    bot.connect(bot.nick, server, port)

cmnds.add('jump', handle_jump, 'OPER')
examples.add('jump', 'jump <server> <port> .. switch server', \
'jump localhost 6667')

def modecb(bot, ievent):
    """ callback to detect change of channel key """
    if ievent.postfix.find('+k') != -1:
        key = ievent.postfix.split('+k')[1]
        bot.channels[ievent.channel]['key'] = key

callbacks.add('MODE', modecb, None)

def handle_nick(bot, ievent):
    """ nick <nickname> .. change bot's nick """
    try:
        nick = ievent.args[0]
    except IndexError:
        ievent.missing('<nickname>')
        return
    # see if nick is already taken
    queue = Queue.Queue()
    bot.wait.register('433', bot.nick, queue, 5)
    bot.setnick(nick)
    result = queue.get()
    if result:
        ievent.reply('nick %s is already in use' % nick)
        return
    config.set('nick', nick)

cmnds.add('nick', handle_nick, 'OPER')
examples.add('nick', 'nick <nickname> .. set nick of the bot', 'nick mekker')

def handle_sendraw(bot, ievent):
    """ sendraw <txt> .. send raw text to the server """
    bot.sendraw(ievent.rest)

cmnds.add('sendraw', handle_sendraw, 'SENDRAW')
examples.add('sendraw', 'sendraw <txt> .. send raw string to the server', \
'sendraw PRIVMSG #dunkbots :yo!')

def handle_nicks(bot, ievent):
    """ nicks .. return nicks on channel """
    try:
        chan = ievent.args[0]
    except:
        chan = ievent.channel
    queue = Queue.Queue()
    # set callback for name info response
    wait353 = bot.wait.register('353', chan, queue)
    # 366 is end of names response list
    wait366 = bot.wait.register('366', chan, queue)
    result = ""
    bot.names(chan)
    while(1):
        qres = queue.get()
        if qres == None:
            break
        if qres.cmnd == '366':
            break
        else:
            result += "%s " % qres.txt
    bot.wait.delete(wait353)
    bot.wait.delete(wait366)
    if result:
        ievent.reply("nicks on %s = %s" % (chan, result))
    else:
        ievent.reply("can't get nicks of channel %s" % chan)

cmnds.add('nicks', handle_nicks, ['USER', 'WEB'])
examples.add('nicks', 'show nicks on channel the command was given in', \
'nicks')

def handle_silent(bot, ievent):
    """ silent .. set silent mode of channel """
    ievent.reply('putting %s to silent mode' % ievent.channel)
    bot.channels[ievent.channel]['silent'] = 1

cmnds.add('silent', handle_silent, 'OPER')
examples.add('silent', 'set silent mode on channel the command was given \
in', 'silent')

def handle_loud(bot, ievent):
    """ loud .. enable output to the channel """
    bot.channels[ievent.channel]['silent'] = 0
    ievent.reply('%s put into loud mode' % ievent.channel)

cmnds.add('loud', handle_loud, 'OPER')
examples.add('loud', 'disable silent mode of channel command was given \
in', 'loud')

def handle_reconnect(bot, ievent):
    """ reconnect .. reconnect to server """
    bot.reconnect()

cmnds.add('reconnect', handle_reconnect, 'OPER')
examples.add('reconnect', 'reconnect to server', 'reconnect')
